<?

	// M2.php - rewritten Media class. Because I can't put it off any longer
	
	
class MediaArea {

	var $ID, $title, $description, $image_max_width, $image_max_height, $image_max_thumbnail_width, $image_max_thumbnail_height;
	var $is_general_media, $parent_id, $allowed_extensions;
	
	function getID() {return $this->ID;}
	function getTitle() {return $this->title;}
	function getDescription() {return $this->description;}
	function getMaxWidth() {return $this->image_max_width;}
	function getMaxHeight() {return $this->image_max_height;}
	function getMaxThumbnailWidth() {return $this->image_max_thumbnail_width;}
	function getMaxThumbnailHeight() {return $this->image_max_thumbnail_height;}
	function isGeneralMedia() {return $this->is_general_media;}
	function getParentID() {return $this->parent_id;}
	function getAllowedExtensions() {return $this->allowed_extensions;}
	function getAllowedExtensionsArray() {return explode(',', $this->allowed_extensions);}
	function getDisplay() {return $this->display;}
	function isActive() {return $this->is_active;}
	function getNumFiles() {
		$q = "select count(ID) as total from DarkRoom_Media_to_Areas where area_id = {$this->ID}";
		$r = mysql_query($q);
		if (!$r) {
			return Error::MySQL();
		}
		$row = mysql_fetch_assoc($r);
		if ($row['total'] > 0) {
			return $row['total'];
		} else {
			return 0;
		}
	}
	
	function get($areaID) { // static method
		$db = new db;
		$areaID = $db->sanitize_to_db($areaID);
		if ($areaID > 0 && is_numeric($areaID)) {		
			$q = "select * from DarkRoom_Areas where ID = {$areaID}";
			$r = mysql_query($q);
			$row = mysql_fetch_assoc($r);
			
			$ma = new MediaArea;
			if ($row['ID']) {
				foreach($row as $key => $value) {
					$ma->{$key} = $db->sanitize_from_db($value);
				}
				
				return $ma;
			}
		}
		
		// if we get down here, we've failed
		$e = new Error();
		$e->add('Invalid area ID.');
		return $e;
	}
	
	function activate() {
		$e = new Error();
		if (User::isAdmin()) {
			$q = "update DarkRoom_Areas set is_active = 1 where ID = {$this->ID}";
			$r = mysql_query($q);
			if (!$r) {
				$e->add(mysql_error());
				return $e;
			}
		} else {
			$e->add('Only an administrator may activate areas.');
			return $e;
		}
	}
	
	function deactivate() {
		$e = new Error();
		if (User::isAdmin()) {
			$q = "update DarkRoom_Areas set is_active = 0 where ID = {$this->ID}";
			$r = mysql_query($q);
			if (!$r) {
				$e->add(mysql_error());
				return $e;
			}
		} else {
			$e->add('Only an administrator may deactivate areas.');
			return $e;
		}
	}
	
	function delete() {
		$e = new Error();
		if (User::isAdmin()) { 
			$q = "select ID from DarkRoom_Media_to_Areas where area_id = {$this->ID}";
			$r = mysql_query($q);
			if ($r) {
				while($row = mysql_fetch_assoc($r)) {
					$mi = MediaInstance::get($row['ID']);
					if (!db::isError($mi)) {
						$res = $mi->delete();
						if (db::isError($res)) {
							$e->add($res);
						}
					} else {
						$e->add($mi);
					}
				}
				
				if (!$e->hasErrors()) {
					// first, we update all the areas that were directly underneath this error to have the parent id of this area's parent
					$q = "update DarkRoom_Areas set parent_id = {$this->parent_id} where parent_id = {$this->ID}";
					$r = mysql_query($q);
					if ($r) {
						$q = "delete from DarkRoom_Media_to_Areas where area_id = {$this->ID}";
						$r1 = mysql_query($q);
						$q = "delete from DarkRoom_Areas where ID = {$this->ID}";
						$r2 = mysql_query($q);
						
						if ($r1 && $r2) {
							return true;
						} else {
							$e->add(mysql_error());
							return $e;
						}						
					} else {
						$e->add(mysql_error());
						return $e;
					}
					
					
					
				}
			} else {
				$e->add(mysql_error());
				return $e;
			}		
		} else {
			$e->add('Only an administrator may delete areas.');
			return $e;
		}
	}
	
	function getActive($areaID) { // static method
		$db = new db;
		$areaID = $db->sanitize_to_db($areaID);
		if ($areaID > 0 && is_numeric($areaID)) {		
			$q = "select * from DarkRoom_Areas where ID = {$areaID} and is_active = 1";
			$r = mysql_query($q);
			$row = mysql_fetch_assoc($r);
			
			$ma = new MediaArea;
			if ($row['ID']) {
				foreach($row as $key => $value) {
					$ma->{$key} = $db->sanitize_from_db($value);
				}
				
				return $ma;
			}
		}
		
		// if we get down here, we've failed
		$e = new Error();
		$e->add('Invalid area ID.');
		return $e;
	}
	
	function getMedia($isActive = null) {
		$isActive = (isset($isActive)) ? 'and is_active = ' . $isActive : '';
		$q = "select ID from DarkRoom_Media_to_Areas where DarkRoom_Media_to_Areas.area_id = {$this->ID} {$isActive} order by DarkRoom_Media_to_Areas.display_order asc"; 
		$r = mysql_query($q);
		if ($r) {
			$mArray = array();
			while ($row = mysql_fetch_assoc($r)) {
				$mArray[] = MediaInstance::get($row['ID']);
			}
			return $mArray;
		} else {
			$e = new Error();
			$e->add(mysql_error());
			return $e;
		}
	}
	
	function getAreas() {
		// returns areas beneath this one

		// can be called statically to get a list from the top level
		if (is_object($this)) {
			$parentID = ($this->ID) ? $this->ID : 0;
		}
		else {
			$parentID = 0;
		}

		$q = "select ID from DarkRoom_Areas where parent_id = {$parentID}";
		$r = mysql_query($q);

		if ($r) {
			$aAreas = array();
			while ($row = mysql_fetch_assoc($r)) {
				$aAreas[] = MediaArea::get($row['ID']);
			}
			return $aAreas;
		} else {
			$e = new Error();
			$e->add(mysql_error());
			return $e;
		}
	}
	
	function getGeneralAreas($isActive = null) {
		// returns areas beneath this one

		// can be called statically to get a list from the top level
		if (is_object($this)) {
			$parentID = ($this->ID) ? $this->ID : 0;
		}
		else {
			$parentID = 0;
		}

		$isActive = (isset($isActive)) ? 'and is_active = ' . $isActive : '';

		$q = "select ID from DarkRoom_Areas where parent_id = {$parentID} and is_general_media = 1 {$isActive}";
		$r = mysql_query($q);

		if ($r) { 
			$aAreas = array();
			while ($row = mysql_fetch_assoc($r)) {
				$aAreas[] = MediaArea::get($row['ID']);
			}
			return $aAreas;
		} else {
			$e = new Error();
			$e->add(mysql_error());
			return $e;
		}
	}
	
	function getAllGeneralAreas() {
		$q = "select parent_id, ID from DarkRoom_Areas where is_general_media = 1";
		$r = mysql_query($q);
		$aAreas = array();
		if ($r) {
			if ($this) {
				$excludedParentIDs[] = $this->ID;
			}
			while ($row = mysql_fetch_assoc($r)) {
				if (!in_array($row['parent_id'], $excludedParentIDs)) {
					$aAreas[] = MediaArea::get($row['ID']);
				} else {
					$excludedParentIDs[] = $row['ID'];
				}
			}
			return $aAreas;
		} else {
			$e = new Error();
			$e->add(mysql_error());
			return $e;
		}
	}
	
	function isValidAreaTarget($a) {
		if ($a->isGeneralMedia()) {
			// get an array of all the parent IDs that this area can't be moved into
			$q = "select parent_id, ID from DarkRoom_Areas where is_general_media = 1";
			$r = mysql_query($q);
			if ($r) {
				if ($this) {
					$excludedParentIDs[] = $this->ID;
				}
				while ($row = mysql_fetch_assoc($r)) {
					if (in_array($row['parent_id'], $excludedParentIDs)) {
						$excludedParentIDs[] = $row['ID'];
					}
				}
				if (!in_array($a->getParentID(), $excludedParentIDs)) {
					return true;
				}
			} else {
				$e = new Error();
				$e->add(mysql_error());
				return $e;
			}
		} else {
			$e = new Error();
			$e->add("Invalid area target.");
			return $e;
		}
	}
	
	function updateInformation($postArray, $filterObj = null) {
		if ($filterObj) {
			$proceed = $filterObj->validateMediaOperation("UPDATEINFO", $this);
			if (db::isError($proceed)) {
				return $proceed;
			}
		}
		$db = new db;		
		$title = $db->sanitize_to_db($_POST['title']);
		$description = $db->sanitize_to_db($_POST['description']);
		$parent_id = 0;
		if ($_POST['parent_id']) {
			$ma = MediaArea::get($_POST['parent_id']);
			if (!db::isError($ma)) {
				$res = $this->isValidAreaTarget($ma);
				if (!db::isError($res)) {
					$parent_id = $ma->getID();
				} 
			}
		}
		
		if (!db::isError($ma) && !db::isError($res)) {
			$q = "update DarkRoom_Areas set title = '{$title}', description = '{$description}', parent_id = {$parent_id} where ID = {$this->ID}";
			$r = mysql_query($q);
			if ($r) {
				return $r;
			} else {
				$e = new Error();
				$e->add(mysql_error());
				return $e;
			}
		}
	}			
	
	function updatePreferences($postArray) {
		if (User::isAdmin()) {
			$db = new db;
			$image_max_width = $db->sanitize_to_db($postArray['image_max_width']);
			$image_max_height = $db->sanitize_to_db($postArray['image_max_height']);
			$image_max_thumbnail_width = $db->sanitize_to_db($postArray['image_max_thumbnail_width']);
			$image_max_thumbnail_height = $db->sanitize_to_db($postArray['image_max_thumbnail_height']);
			if (isset($postArray['title']) && isset($postArray['description'])) {
				$title = $db->sanitize_to_db($postArray['title']);
				$description = $db->sanitize_to_db($postArray['description']);			
				$q = "update DarkRoom_Areas set image_max_width = {$image_max_width}, image_max_height = {$image_max_height}, image_max_thumbnail_width = {$image_max_thumbnail_width}, image_max_thumbnail_height = {$image_max_thumbnail_height}, title = '{$title}', description = '{$description}' where ID = {$this->ID}";
			} else {
				$q = "update DarkRoom_Areas set image_max_width = {$image_max_width}, image_max_height = {$image_max_height}, image_max_thumbnail_width = {$image_max_thumbnail_width}, image_max_thumbnail_height = {$image_max_thumbnail_height} where ID = {$this->ID}";
			}
			$r = mysql_query($q);
			if ($r) {
				return $r;
			} else {
				$e = new Error();
				$e->add(mysql_error());
				return $e;
			}
		} else {
			$e = new Error();
			$e->add("Only an administrator may update area preferences.");
			return $e;
		}
	}
	
	function add($is_general_media, $title, $description, $allowed_extensions, $display) {
		$db = new db;
		if (User::isAdmin()) { 
			$parentID = $db->sanitize_to_db($parentID);
			$is_general_media = $db->sanitize_to_db($is_general_media);
			$title = $db->sanitize_to_db($title);
			$description = $db->sanitize_to_db($description);
			$allowed_extensions = $db->sanitize_to_db($allowed_extensions);
			$display = ($display == 'grid') ? 'grid' : 'list';
			if (strtolower(get_class($this)) == "mediaarea") {
				$parentID = $this->getID();
			} else {
				$parentID = 0;
			}
			if (!$title) {
				$title = '(Untitled Area)';
			}
			$q = "insert into DarkRoom_Areas (title, description, image_max_width, image_max_height, image_max_thumbnail_width, image_max_thumbnail_height, is_general_media, parent_id, allowed_extensions, display) values ('$title','$description'," . MEDIA_DEFAULT_MAX_WIDTH . "," . MEDIA_DEFAULT_MAX_HEIGHT . "," . MEDIA_DEFAULT_MAX_THUMBNAIL_WIDTH . "," . MEDIA_DEFAULT_MAX_THUMBNAIL_HEIGHT . ",  $is_general_media, $parentID, '$allowed_extensions', '$display')";
			$r = mysql_query($q);
			if ($r) {
				$ma = MediaArea::get(mysql_insert_id());
				return $ma;
			} else {
				$e = new Error();
				$e->add(mysql_error());
				return $e;
			}
		}
	}
	
	function rescan($filterObj = null) {
		if ($filterObj) {
			$proceed = $filterObj->validateMediaOperation("RESCAN");
			if (db::isError($proceed)) {
				return $proceed;
			}
		}
		$q = "select DarkRoom_Media.ID, DarkRoom_Media.filename, DarkRoom_Media.date_time, DarkRoom_Media.filename_original from DarkRoom_Media, DarkRoom_Media_to_Areas where DarkRoom_Media.ID = DarkRoom_Media_to_Areas.media_id and DarkRoom_Media_to_Areas.area_id = {$this->ID} and DarkRoom_Media.type = 'image'";
		$r = mysql_query($q);
		$eArray = array();
		while ($row = mysql_fetch_assoc($r)) {
			$origPath = SITE_FULL_DIRECTORY . MEDIA_ORIGINALS_DIRECTORY . '/' .  date('Ymd', strtotime($row['date_time'])) . '/' . $row['filename_original'];
			$r1 = $this->processImage($origPath, $row['filename'], FULL, true);
			if (db::isError($r1)) {
				$eArray[] = $r1;
			}
			$r2 = $this->processImage($origPath, $row['filename'], THUMBNAIL, true);
			if (db::isError($r2)) {
				$eArray[] = $r2;
			}
			if (count($eArray) > 0) {
				$e = Error::mergeErrors($eArray);
				return $e;
			}
		}
	}
	
	function createImage($originalPath, $newPath, $width, $height) {
		// first, we grab the original image. We shouldn't ever get to this function unless the image is valid
		$imageSize = getimagesize($originalPath);
		$oWidth = $imageSize[0];
		$oHeight = $imageSize[1];
		$finalWidth = 0;
		$finalHeight = 0;
		
		// first, if what we're uploading is actually smaller than width and height, we do nothing
		if ($oWidth < $width && $oHeight < $height) {
			$finalWidth = $oWidth;
			$finalHeight = $oHeight;
		} else {
			// otherwise, we do some complicated stuff
			// first, we subtract width and height from original width and height, and find which difference is greater
			$wDiff = $oWidth - $width;
			$hDiff = $oHeight - $height;
			if ($wDiff > $hDiff) {
				// there's more of a difference between width than height, so if we constrain to width, we should be safe
				$finalWidth = $width;
				$finalHeight = $oHeight / ($oWidth / $width);
			} else {
				// more of a difference in height, so we do the opposite
				$finalWidth = $oWidth / ($oHeight / $height);
				$finalHeight = $height;
			}
		}
	
		$image = imageCreateTrueColor($finalWidth, $finalHeight);
		switch($imageSize[2]) {
			case IMAGETYPE_GIF:
				$im = imageCreateFromGIF($originalPath);
				break;
			case IMAGETYPE_JPEG:
				$im = imageCreateFromJPEG($originalPath);
				break;
			case IMAGETYPE_PNG:
				$im = imageCreateFromPNG($originalPath);
				break;
		}
		
		if ($im) {
			$res = imageCopyResampled($image, $im, 0, 0, 0, 0, $finalWidth, $finalHeight, $oWidth, $oHeight);
			if ($res) {
				switch($imageSize[2]) {
					case IMAGETYPE_GIF:
						if (function_exists("imageGIF")) {
							$res2 = imageGIF($image, $newPath);
						} else {
							$res2 = imagePNG($image, $newPath);						
						}
						break;
					case IMAGETYPE_JPEG:
						$res2 = imageJPEG($image, $newPath, 80);
						break;
					case IMAGETYPE_PNG:
						$res2 = imagePNG($image, $newPath, 80);
						break;
				}
			}
		}
		
		if (!$res2) {
			return Error::create("Error creating image.");
		}
	}
	
	function processImage($path, $filename, $type = FULL, $rescan = false) {
		$e = new Error();
		if (file_exists($path)) {
			$dirBase = SITE_FULL_DIRECTORY;
			$dirFiles = ($type == THUMBNAIL) ?  MEDIA_BASE_DIRECTORY . "/" . $this->ID . "/thumbnails"
				: MEDIA_BASE_DIRECTORY . "/" . $this->ID;
				
			$dir = $dirBase . $dirFiles;	
				
			if (!file_exists($dir)) {
				$r1 = mkdir($dir);
				if ($r1) {
					$r2 = chmod($dir, 0777);
					if (!$r2) {
						$e->add("Unable to set directory permissions: " . $dirFiles);
						return $e;
					}
				} else {
					$e->add("Unable to create directory: " . $dirFiles);
					return $e;
				}			
			}
			
			if (file_exists($dir . '/' . $filename) && !$rescan) {
				$prefix = 1;
				while(file_exists($dir . '/' . $prefix . $filename)) {
					$prefix++;
				}
				$filename = $prefix . $filename;
			}
			
			$newPath = $dir.'/'.$filename;
			$imageSize = @getimagesize($path);
			
			if ($type == THUMBNAIL) {
				if (($imageSize[0] > $this->image_max_thumbnail_width) || ($imageSize[1] > $this->image_max_thumbnail_height)) {
					$res = $this->createImage($path, $newPath, $this->image_max_thumbnail_width, $this->image_max_thumbnail_height);
					if (db::isError($res)) {
						return $res;
					} else {
						// otherwise return the filename
						return $filename;
					}
				} else {
					$r3 = copy($path, $newPath);
					if (!$r3) {
						$e->add("Unable to copy file to directory: " . $dirFiles);
						return $e;
					}
					return $filename;
				}
			} else { // type = FULL 
				if (($imageSize[0] > $this->image_max_width) || ($imageSize[1] > $this->image_max_height)) {
					$res = $this->createImage($path, $newPath, $this->image_max_width, $this->image_max_height);
					if (db::isError($res)) {
						return $res;
					} else {
						// otherwise return the filename
						return $filename;
					}
				} else {
					$r3 = copy($path, $newPath);
					if (!$r3) {
						$e->add("Unable to copy file to directory: " . $dirFiles);
						return $e;
					}
					return $filename;
				}
			}
		} else {
			$e->add("File not found: " . $path);
			return $e;
		}
	}

	function isValidExtension($filename) {
		$ext = Media::getExtension($filename);
		$extensions = $this->getAllowedExtensionsArray();
		return in_array(strtolower($ext), $extensions);
	}
	
	function getCurrentDisplayOrder() {
		$q = "select count(ID) as total from DarkRoom_Media_to_Areas where area_id = {$this->ID}";
		$r = @mysql_query($q);
		if ($r) {
			$row = mysql_fetch_assoc($r);
			return $row['total'] + 1;
		} else {
			$e = new Error();
			$e->add(mysql_error());
			return $e;
		}
	}
	
	function updateDisplayOrder() {
		$displayOrder = 1;
		$q = "select ID from DarkRoom_Media_to_Areas where area_id = {$this->ID} order by display_order asc";
		$r = mysql_query($q);
		if (!$r) {
			return Error::MySQL();
		}
		while ($row = mysql_fetch_assoc($r)) {
			$q2 = "update DarkRoom_Media_to_Areas set display_order = {$displayOrder} where ID = {$row['ID']}";
			$r2 = mysql_query($q2);
			$displayOrder++;
			if (!$r2) {
				return Error::MySQL();
			}
		}
		return true;
	}
	
	function getAreaTrail() {
		$trail = array();
		$trail[$this->ID] = $this;
		$currentParent = $this->parent_id;
		while ($currentParent > 0) {
			$q = "select ID, parent_id from DarkRoom_Areas where ID = {$currentParent}";
			$r = mysql_query($q);
			if ($r) {
				$row = mysql_fetch_assoc($r);
				$trail[$currentParent] = MediaArea::get($row['ID']);
				$currentParent = $row['parent_id'];
			} else {
				$e = new Error();
				$e->add(mysql_error());
				break;
				
				return $e;
			}
		}
		$trail = array_reverse($trail);
		return $trail;
	}
	
	function addAllMediaIncoming($keepCopy = false, $filterObj = null) {
		if ($filterObj) {
			$proceed = $filterObj->validateMediaOperation("ADD");
			if (db::isError($proceed)) {
				return $proceed;
			}
		}
		$incDir = SITE_FULL_DIRECTORY . MEDIA_INCOMING_DIRECTORY;
		$dirHandle = @opendir($incDir);
		if ($dirHandle) {
			$eArray = array();
			while (false !== ($file = readdir($dirHandle))) {
				if ($file != '.' && $file != '..') {
					$res = $this->addMediaIncoming($file, $keepCopy);
				}
			}
			if (!db::isError($res)) {
				return true;
			} else {
				return $res;
			}
		} else {
			$e = new Error();
			$e->add("Unable to access incoming files directory: " . SITE_WEB_DIRECTORY . MEDIA_INCOMING_DIRECTORY);
			return $e;
		}
	}
		
	function addMediaIncoming($file, $keepCopy = false, $filterObj = null) {
		if ($filterObj) {
			$proceed = $filterObj->validateMediaOperation("ADD");
			if (db::isError($proceed)) {
				return $proceed;
			}
		}
		$db = new db;
		$dirDate = $db->get_local_datetime('Ymd');
		$origDir = SITE_FULL_DIRECTORY . MEDIA_ORIGINALS_DIRECTORY . "/$dirDate";
		$fixedFile = Media::sanitizeFile($file);
		if (file_exists($origDir . '/' . $fixedFile)) {
			$prefix = 1;
			while(file_exists($origDir . '/' . $prefix . $fixedFile)) {
				$prefix++;
			}
			$fixedFile = $prefix . $fixedFile;
		}
		$origFile = $origDir . '/' . $fixedFile;
		
		$e = new Error();
		if ($this->isValidExtension($origFile)) {
			if (!file_exists($origDir)) {
				$r1 = mkdir($origDir);
				if ($r1) {
					$r2 = chmod($origDir, 0777);
					if (!$r2) {
						$e->add("Unable to set directory permissions: " . SITE_WEB_DIRECTORY . MEDIA_ORIGINALS_DIRECTORY . "/$dirDate");
						return $e;
					}
				} else {
					$e->add("Unable to create directory: " . SITE_WEB_DIRECTORY . MEDIA_ORIGINALS_DIRECTORY . "/$dirDate");
					return $e;
				}			
			}		
			
			$r3 = copy(SITE_FULL_DIRECTORY . MEDIA_INCOMING_DIRECTORY . '/' . $file, $origFile);
			if (!$r3) {
				$e->add("Unable to copy file: " . SITE_WEB_DIRECTORY . MEDIA_INCOMING_DIRECTORY . '/' . $file);
				return $e;
			}	
			$date_time = $db->get_local_datetime();
			$extension = Media::getExtension($origFile);
			$imageSize = @getimagesize($origFile);
			if ($imageSize[2] == IMAGETYPE_GIF || $imageSize[2] == IMAGETYPE_PNG || $imageSize[2] == IMAGETYPE_JPEG) {
				$r4 = $this->processImage($origFile, $fixedFile);
				if (db::isError($r4)) {
					return $r4;
				}
				$r5 = $this->processImage($origFile, $fixedFile, THUMBNAIL);
				if (db::isError($r5)) {
					return $r5;
				}
				$type = 'image';
				
				if (!db::isError($r4)) {
					// we assume that the filename is correct
					$filename = $r4;
				}
			} else {
				$filename = $fixedFile;
			}
			
			/*
			// we now no longer use processFile, because why do we need two copies of the same large mp3 
			// floating around on these webhosts with limited space? 
			else {
				$r4 = $this->processFile($origFile, $randNum . '_' . $dirDate . '_' . $fixedFile);
				$type = $extension;
				if (db::isError($r4)) {
					return $r4;
				}
			}*/
		} else {
			$e->add("Invalid extension. Valid extensions are: " . $this->getAllowedExtensions());
			return $e;
		}
		
		$res = @mysql_query("insert into DarkRoom_Media (date_time, filename, filename_original, type) values ('$date_time', '" . $filename . "', '" . $fixedFile . "', '" . $type . "')");
		if (!$res) {
			$e->add(mysql_error());
			return $e;
		}
		$mediaID = mysql_insert_id();
		$uo = User::getCurrent();
		$userID = $uo->getID();
		
		$this->updateDisplayOrder();
		$do = $this->getCurrentDisplayOrder();
		
		$res2 = @mysql_query("insert into DarkRoom_Media_to_Areas (title, area_id, media_id, is_active, display_order, user_id) values ('(untitled)', {$this->ID}, {$mediaID}, 0, {$do}, {$userID})");
		if (!$res2) {
			$e->add(mysql_error());
			return $e;
		}
		
		if ($keepCopy == 0) {
			$unl = @unlink(SITE_FULL_DIRECTORY . MEDIA_INCOMING_DIRECTORY . '/' . $file);
			if (!$unl) {
				$e->add("Unable to remove original incoming file: " . SITE_WEB_DIRECTORY . MEDIA_INCOMING_DIRECTORY . '/' . $file);
				return $e;
			}
		}
		$mediaInstanceID = mysql_insert_id();
		return $mediaInstanceID;
	}
	
	function addMediaUpload($fieldname, $filterObj = null) {
		if ($filterObj) {
			$proceed = $filterObj->validateMediaOperation("ADD");
			if (db::isError($proceed)) {
				return $proceed;
			}
		}
		$db = new db;
		$dirDate = $db->get_local_datetime('Ymd');
		$e = new Error();
		if (is_uploaded_file($_FILES[$fieldname]['tmp_name'])) {
			
			$origDir = SITE_FULL_DIRECTORY . MEDIA_ORIGINALS_DIRECTORY . "/$dirDate";
			$fixedFile = Media::sanitizeFile($_FILES[$fieldname]['name']);
			if (file_exists($origDir . '/' . $fixedFile)) {
				$prefix = 1;
				while(file_exists($origDir . '/' . $prefix . $fixedFile)) {
					$prefix++;
				}
				$fixedFile = $prefix . $fixedFile;
			}
			$origFile = $origDir . '/' . $fixedFile;
			if ($this->isValidExtension($origFile)) {
				if (!file_exists($origDir)) {
					$r1 = mkdir($origDir);
					if ($r1) {
						$r2 = chmod($origDir, 0777);
						if (!$r2) {
							$e->add("Unable to set directory permissions: " . SITE_WEB_DIRECTORY . MEDIA_ORIGINALS_DIRECTORY . "/$dirDate");
							return $e;
						}
					} else {
						$e->add("Unable to create directory: " . SITE_WEB_DIRECTORY . MEDIA_ORIGINALS_DIRECTORY . "/$dirDate");
						return $e;
					}			
				}
				
				$r3 = @copy($_FILES[$fieldname]['tmp_name'], $origFile);
				if (!$r3) {
					$e->add("Unable to temporary file to location: " . SITE_WEB_DIRECTORY . MEDIA_ORIGINALS_DIRECTORY . "/$dirDate");
					return $e;
				}
				
				$date_time = $db->get_local_datetime();
				$extension = Media::getExtension($origFile);
				
				$imageSize = @getimagesize($origFile);
				if ($imageSize[2] == IMAGETYPE_GIF || $imageSize[2] == IMAGETYPE_PNG || $imageSize[2] == IMAGETYPE_JPEG) {
					$r4 = $this->processImage($origFile, $fixedFile);
					if (db::isError($r4)) {
						return $r4;
					}
					$r5 = $this->processImage($origFile, $fixedFile, THUMBNAIL);
					if (db::isError($r5)) {
						return $r5;
					}
					$type = 'image';
						if (!db::isError($r4)) {
						// we assume that the filename is correct
						$filename = $r4;
					}
				}  else {
					$filename = $fixedFile;
				}
				
				/* else {
					$r4 = $this->processFile($origFile, $randNum . '_' . $dirDate . '_' . $fixedFile);
					$type = $extension;
					if (db::isError($r4)) {
						return $r4;
					}
				}*/
				
			} else {
				$e->add("Invalid extension. Valid extensions are: " . $this->getAllowedExtensions());
				return $e;
			}
			
			$res = @mysql_query("insert into DarkRoom_Media (date_time, filename, filename_original, type) values ('$date_time', '" . $filename . "', '" . $fixedFile . "', '" . $type . "')");
			if (!$res) {
				$e->add(mysql_error());
				return $e;
			}
			$mediaID = mysql_insert_id();
			$this->updateDisplayOrder();
			$do = $this->getCurrentDisplayOrder();
			
			$uo = User::getCurrent();
			$userID = $uo->getID();
			
			$res2 = @mysql_query("insert into DarkRoom_Media_to_Areas (title, area_id, media_id, is_active, display_order, user_id) values ('(untitled)', {$this->ID}, {$mediaID}, 0, {$do}, {$userID})");
			if (!$res2) {
				$e->add(mysql_error());
				return $e;
			}
			$mediaInstanceID = mysql_insert_id();
			return $mediaInstanceID;
		} else {
			$e->add("A valid file was not uploaded.");
			return $e;
		}
	}
	
	function addMediaRemote($url, $filterObj = null) {
		if ($filterObj) {
			$proceed = $filterObj->validateMediaOperation("ADD");
			if (db::isError($proceed)) {
				return $proceed;
			}
		}
		$e = new Error();
		$filename = basename($url);
		if ($filename) {
			$file = @fopen($url, 'r');
			if ($file) {
				while (!feof($file)) {
					$tempfile .= fread($file, 4096);
				}
				
				$orig_file_path = $orig_dir . '/' . $filename;
				$fp = @fopen(SITE_FULL_DIRECTORY . MEDIA_INCOMING_DIRECTORY . '/' . $filename, 'wb');
				if ($fp) {
					fputs($fp, $tempfile, strlen($tempfile));
					fclose($fp);
					$success = true;
				} else {
					$e->add("Error opening file for writing: " . SITE_WEB_DIRECTORY . MEDIA_INCOMING_DIRECTORY . '/' . $filename);
					return $e;
				}
				
				if ($success) {
					return $this->addMediaIncoming($filename);			
				}
			}
		}
		
		$e->add("Invalid file specified.");
		return $e;	
	}
	
	function addMediaAlias($mediaFormArray) {
		$uo = User::getCurrent();
		$userID = $uo->getID();
		if (is_array($mediaFormArray)) {
			foreach($mediaFormArray as $mediaID) {
				$this->updateDisplayOrder();
				$do = $this->getCurrentDisplayOrder();
				$a = mysql_query('insert into DarkRoom_Media_to_Areas (title, area_id, media_id, display_order, is_alias, user_id) values (\'(untitled)\', ' . $this->ID . ', ' . $mediaID . ', ' . $do . ', 1, ' . $userID . ')');
				$r = mysql_query('select filename, filename_original, date_time, type from DarkRoom_Media where ID = ' . $mediaID);
				if ($a && $r) {
					$obj = mysql_fetch_object($r);
					$origPath = SITE_FULL_DIRECTORY . MEDIA_ORIGINALS_DIRECTORY . '/' .  date('Ymd', strtotime($obj->date_time)) . '/' . $obj->filename_original;
					if ($obj->type == 'image') { 
						$r1 = $this->processImage($origPath, $obj->filename, FULL);
						if (!db::isError($r1)) {
							$r2 = $this->processImage($origPath, $obj->filename, THUMBNAIL);
							if (db::isError($r2)) {
								return $r2;
							}
						} else {
							return $r1;
						}
					} 
				} else {
					$e = new Error();
					$e->add(mysql_error());
					return $e;
				}
			}
			
			return true;
		} else {
			$e = new Error();
			$e->add("Invalid alias form input.");
			return $e;
		}
	}	
		
	function getMediaByDisplayOrder($display_order) {
		$q = "SELECT ID FROM DarkRoom_Media_to_Areas WHERE area_id = {$this->ID} AND display_order = {$display_order}";
		$r = @mysql_query($q);

		if (!$r) {
			$e = new Error();
			$e->add(mysql_error());
			return $e;
		}

		$row = mysql_fetch_assoc($r);
		$id = $row['ID'];

		if (!isset($id)) {
			return null;
		}

		$ma = MediaInstance::get($id);

		return $ma;
	}
}

class Media {
	
	/* static methods */
	function sanitizeFile($file) {
		$search = "/[^0-9A-Za-z-.]/";
		$replace = "";
		return preg_replace($search, $replace, $file);
	}
	
	
	function getExtension($filename) { // static method
		return substr(strrchr($filename, '.'), 1);
	}
	
	
	function getIncomingFiles() {
		$aFiles = array();
		$dir = SITE_FULL_DIRECTORY . MEDIA_INCOMING_DIRECTORY;
		$dir = @opendir($dir);
		if ($dir) {
			while (false != ($file = readdir($dir))) { 
				if (($file != ".") && ($file != "..") && $file != "index.html") {
					$aFiles[] = $file;
				}
			}
			return $aFiles;
		} else {
			$e = new Error();
			$e->add("The system was unable to locate or read your incoming directory.");
			return $e;
		}
	}
	
	function isValidExtension($filename, $extensionList) {
		$ext = Media::getExtension($filename);
		$extensions = explode(',', $extensionList);
		return in_array(strtolower($ext), $extensions);
	}
	
	function output($url) {
		$args = func_get_args();
		$alt = ($args[1]) ? $args[1] : '';
		$class = ($args[2]) ? "class=\"{$args[2]}\"" : "";
		$size = @getimagesize(SITE_FULL_DIRECTORY . $url);
		if (is_array($size)) {
			return '<img ' . $class . 'alt="' . $alt . '" src="' . SITE_WEB_DIRECTORY . $url . '" ' . $size[3] . '>';
		} else {
			$e = new Error();
			$e->add("Specified url was not a valid image.");
			return $e;
		}
	}
	
	
}

class MediaInstance {
	
	/* object methods */
	
	/* instance variables */
	var $ID, $title, $description, $is_alias, $media_id, $area_id, $display_order, $is_active, $user_id, $access;
	
	/* media variables */
	var $filename, $type, $date_time; // removed filename_original - instead we reconstruct the path
	
	function getDisplayOrder() {return $this->display_order;}
	function getAreaID() {return $this->area_id;}
	function getAreaObject() {
		$ma = MediaArea::get($this->area_id);
		return $ma;
	}
	function getMediaID() {return $this->media_id;}
	function isAlias() {return $this->is_alias;}
	function getDescription() {return $this->description;}
	function getTitle() {return $this->title;}
	function getID() {return $this->ID;}
	function isActive() {return $this->is_active;}
	function getAccess() {return $this->access;}
	function getProtectedFilename() {return $this->protected_filename;}
	
	// media-specific
	function getFilename() {return $this->filename;}
	function getType() {return $this->type;}
	
	//function getFilenameOriginal() {return $this->filename_original;}
	
	function getDateTime($dateMask = null) {
		$dateMask = (!$dateMask) ? "Y-m-d" : $dateMask;
		return date($dateMask, strtotime($this->date_time));
	}
	function getUserID() {return $this->user_id;}
	
	function update($postArray, $filterObj = null) {
		if ($filterObj) {
			$proceed = $filterObj->validateMediaOperation("UPDATE");
			if (db::isError($proceed)) {
				return $proceed;
			}
		}
		$db = new db;
		$title = $db->sanitize_to_db($postArray['title']);
		$description = $db->sanitize_to_db($postArray['description']);
		$u = User::getCurrent();
		if ($u->isAdmin()) {
			$access = $db->sanitize_to_db($postArray['access']);
			if ($access == 'STREAMING') {
				$result = $this->setupStreaming();
				if ($db->isError($result)) {
					return $result;
				}
			}
			$q = "update DarkRoom_Media_to_Areas set title = '{$title}', description = '{$description}', access = '{$access}' where ID = " . $this->ID;
		} else {
			$q = "update DarkRoom_Media_to_Areas set title = '{$title}', description = '{$description}' where ID = " . $this->ID;
		}
		$r = mysql_query($q);
		if ($r) {
			return $r;
		} else {
			$e = new Error();
			$e->add(mysql_error());
			return $e;
		}
	}
	
	function setupStreaming() {
		include_class('config');
		$conf = new Config();
		$streamingAudioFilesPath = $conf->getSetting('streamingAudioFilesPath');
		$streamingAudioServerURL = $conf->getSetting('streamingAudioServerURL');
		$filename = $this->getProtectedFilename();
		
		if ($filename && file_exists($streamingAudioFilesPath . '/' . $filename)) {
			return true;
		}
		
		if ($streamingAudioFilesPath && !file_exists($streamingAudioFilesPath . '/')) {
			return Error::create("Streaming audio directory either undefined or cannot be found.");
		}
		
		// Create a protected filename
		$prFilename = time() . $this->filename;
		$origPointer = SITE_FULL_DIRECTORY . MEDIA_ORIGINALS_DIRECTORY . '/' . date('Ymd', strtotime($this->date_time)) . '/' . $this->filename_original;
		$newPointer = $streamingAudioFilesPath . '/' . $prFilename;
		$res = @copy($origPointer, $newPointer);
		if (!$res) {
			return Error::create("Unable to copy audio file to streaming audio directory");
		}
		
		$res2 = chmod($origPointer, "000"); // protect original file
			
		$q = "update DarkRoom_Media_to_Areas set protected_filename = '{$prFilename}' where ID = '{$this->ID}'";
		$r = @mysql_query($q);
		if (!$r) {
			return Error::MySQL();
		} else {
			return true;
		}
	}

	function supportsStreaming() {
		$extensions = explode(',', MEDIA_EXTENSIONS_STREAMING);
		return (in_array(Media::getExtension($this->filename), $extensions));
	}
	
	function get($instanceID) {
		if ($instanceID > 0 && is_numeric($instanceID)) {
			$q = "select DarkRoom_Media.date_time, DarkRoom_Media.filename, DarkRoom_Media.filename_original, DarkRoom_Media.type, ";
			$q .= "DarkRoom_Media_to_Areas.* from DarkRoom_Media_to_Areas inner join DarkRoom_Media on DarkRoom_Media_to_Areas.media_id = ";
			$q .= "DarkRoom_Media.ID where DarkRoom_Media_to_Areas.ID = {$instanceID}";
			$r = mysql_query($q);
			$m = new MediaInstance;
			if ($r) {
				$row = mysql_fetch_assoc($r);
				if ($row['ID']) { 
					foreach($row as $key => $value) {
						$m->{$key} = db::sanitize_from_db($value);
					}
					
					return $m;
				}				
			}
		}
		
		$e = new Error();
		$e->add('Invalid media instance ID.');
		return $e;
	}
	
	function delete($filterObj = null) {
		$e = new Error();
		if ($filterObj) {
			$proceed = $filterObj->validateMediaOperation("DELETE");
			if (db::isError($proceed)) {
				return $proceed;
			}
		}
		if ($this->is_alias) {
			if ($this->type == 'image') {
				$loc = SITE_FULL_DIRECTORY . MEDIA_BASE_DIRECTORY . '/' . $this->area_id . '/' . $this->filename;
				if ($this->filename != '' && $this->filename != null) {
					if (file_exists($loc)) {
						$locR = @unlink($loc);
						if (!$locR) {
							$e->add("Unable to delete file: " . MEDIA_BASE_DIRECTORY . '/' . $this->area_id . '/' . $this->filename);
							return $e;
						}
					}
			
					$thumbLoc = SITE_FULL_DIRECTORY . MEDIA_BASE_DIRECTORY . '/' . $this->area_id . '/thumbnails/' . $this->filename;
					if (file_exists($thumbLoc)) {
						$thumbLocR = @unlink($thumbLoc);
						if (!$thumbLocR) {
							$e->add("Unable to delete file: " . MEDIA_BASE_DIRECTORY . '/' . $this->area_id . '/thumbnails/' . $this->filename);
							return $e;
						}
					}
				}
							
			}
			
			$q = "delete from DarkRoom_Media_to_Areas where ID = " . $this->ID;
			$r = mysql_query($q);
			$res = $this->updateDisplayOrder();
			if (db::isError($res)) {
				return $res;
			} else if (!$r) {
				return Error::MySQL();
			} else {
				return true;
			}

		} else {
			// now we cycle through all the media that contain reference to the file. We're going to remove all of them
			// as well as the files in their particular area
			$q = "select area_id from DarkRoom_Media_to_Areas where media_id = {$this->media_id}";
			$r = mysql_query($q);
			if ($r) {
				while ($row = mysql_fetch_assoc($r)) {
					if ($this->filename != '' && $this->filename != null) {
						if ($this->type == 'image') {
							$loc = SITE_FULL_DIRECTORY . MEDIA_BASE_DIRECTORY . '/' . $row['area_id'] . '/' . $this->filename;
							if (file_exists($loc)) {
								$locR = @unlink($loc);
								if (!$locR) {
									$e->add("Unable to delete file: " . MEDIA_BASE_DIRECTORY . '/' . $this->area_id . '/' . $this->filename);
									return $e;
								}
							
								$thumbLoc = SITE_FULL_DIRECTORY . MEDIA_BASE_DIRECTORY . '/' . $row['area_id'] . '/thumbnails/' . $this->filename;
								$thumbLocR = @unlink($thumbLoc);
								if (!$thumbLocR) {
									$e->add("Unable to delete file: " . MEDIA_BASE_DIRECTORY . '/' . $row['area_id'] . '/thumbnails/' . $this->filename);
									return $e;
								}
							}
						}
					}
					// now we remove the original
					if (file_exists(BASE_FULL_DIRECTORY . SITE_WEB_DIRECTORY . MEDIA_ORIGINALS_DIRECTORY . '/' . date('Ymd', strtotime($this->date_time)) . '/' . $this->filename_original)) {
						$r1 = @unlink(BASE_FULL_DIRECTORY . SITE_WEB_DIRECTORY . MEDIA_ORIGINALS_DIRECTORY . '/' . date('Ymd', strtotime($this->date_time)) . '/' . $this->filename_original);
						if (!$r1) {
							$e->add("Unable to delete file: " . MEDIA_ORIGINALS_DIRECTORY . '/' . date('Ymd', strtotime($this->date_time)) . '/' . $this->filename_original);
							return $e;
						}
					}
				}
			
				
				$r2 = mysql_query('delete from DarkRoom_Media_to_Areas where media_id = ' . $this->media_id);
				$r3 = mysql_query('delete from DarkRoom_Media where ID = ' . $this->media_id);			
				if ($r2 && $r3) {
					return true;
				} else {
					$e->add(mysql_error());
					return $e;
				}
			} else {
				$e->add(mysql_error());
				return $e;
			}
		}
	}
	
	function printThumbnail($alt = null, $class = null) {
		if ($this->type == 'image') {
			$url = MEDIA_BASE_DIRECTORY . '/' . $this->area_id . '/thumbnails/' . $this->filename;			
		} else {
			$url = MEDIA_BASE_DIRECTORY . '/generic_thumbnails/' . $this->type . '.gif';
			if (!file_exists($url)) {
				$url = MEDIA_BASE_DIRECTORY . '/generic_thumbnails/generic.gif';
			}
		}
		return Media::output($url, $alt, $class);
	}
	
	function getFileURL() {
		if ($this->type == 'image') {
			// we get the area instance
			$url = SITE_WEB_DIRECTORY . MEDIA_BASE_DIRECTORY . '/' . $this->area_id . '/' . $this->filename;
		} else if ($this->access == 'STREAMING') {
			include_class('config');
			$conf = new Config();
			$streamingAudioServerURL = $conf->getSetting('streamingAudioServerURL');
			$url = $streamingAudioServerURL . '/' .  basename($this->protected_filename, Media::getExtension($this->protected_filename)) . 'pls';
		} else {
			$url = SITE_WEB_DIRECTORY . MEDIA_ORIGINALS_DIRECTORY . '/' .  date('Ymd', strtotime($this->date_time)) . '/' . $this->filename_original;
		}
		return $url;
	}
	
	function moveUp($filterObj = null) {
		if ($filterObj) {
			$proceed = $filterObj->validateMediaOperation("MOVEUP");
			if (db::isError($proceed)) {
				return $proceed;
			}
		}
		$a = MediaArea::get($this->area_id);
		if (!db::isError($a)) {
			$a->updateDisplayOrder();
		}
		$q = "select display_order from DarkRoom_Media_to_Areas where ID = {$this->ID}";
		$r = mysql_query($q);
		if (!$r) {
			return Error::MySQL();
		}
		$row = mysql_fetch_assoc($r);
		if ($row['display_order']) {
			$this->display_order = $row['display_order'];
		}
		
		$newDO = $this->display_order - 1;
		$r1 = mysql_query("update DarkRoom_Media_to_Areas set display_order = {$this->display_order} where display_order = {$newDO} and area_id = {$this->area_id}");
		$r2 = mysql_query("	update DarkRoom_Media_to_Areas set display_order = {$newDO} where ID = {$this->ID}");
		if ($r1 && $r2) {
			return true;
		} else {
			$e = new Error();
			$e->add(mysql_error());
			return $e;
		}
	}
	
	function moveDown($filterObj = null) {
		if ($filterObj) {
			$proceed = $filterObj->validateMediaOperation("MOVEDOWN");
			if (db::isError($proceed)) {
				return $proceed;
			}
		}
		$a = MediaArea::get($this->area_id);
		if (!db::isError($a)) {
			$a->updateDisplayOrder();
		}
		$q = "select display_order from DarkRoom_Media_to_Areas where ID = {$this->ID}";
		$r = mysql_query($q);
		if (!$r) {
			return Error::MySQL();
		}
		$row = mysql_fetch_assoc($r);
		if ($row['display_order']) {
			$this->display_order = $row['display_order'];
		}
		$newDO = $this->display_order + 1;
		$r1 = mysql_query("update DarkRoom_Media_to_Areas set display_order = {$this->display_order} where display_order = {$newDO} and area_id = {$this->area_id}");
		$r2 = mysql_query("	update DarkRoom_Media_to_Areas set display_order = {$newDO} where ID = {$this->ID}");
		if ($r1 && $r2) {
			return true;
		} else {
			$e = new Error();
			$e->add(mysql_error());
			return $e;
		}
	}
	
	function activate($filterObj = null) {
		if ($filterObj) {
			$proceed = $filterObj->validateMediaOperation("ACTIVATE");
			if (db::isError($proceed)) {
				return $proceed;
			}
		}
		$r1 = @mysql_query("update DarkRoom_Media_to_Areas set is_active = 1 where ID = {$this->ID}");
		if ($r1) {
			return true;
		} else {
			$e = new Error();
			$e->add(mysql_error());
			return $e;
		}
	}

	function deactivate($filterObj = null) {
		if ($filterObj) {
			$proceed = $filterObj->validateMediaOperation("DEACTIVATE");
			if (db::isError($proceed)) {
				return $proceed;
			}
		}
		$r1 = @mysql_query("update DarkRoom_Media_to_Areas set is_active = 0 where ID = {$this->ID}");
		if ($r1) {
			return true;
		} else {
			$e = new Error();
			$e->add(mysql_error());
			return $e;
		}
	}
	
	function getAliasCount() {
		$q = "select count(ID) as total from DarkRoom_Media_to_Areas where media_id = {$this->media_id} and is_alias = 1";
		$result = @mysql_query($q);
		if ($result) {
			$obj = @mysql_fetch_object($result);
			return $obj->total;
		} else {
			$e = new Error();
			$e->add(mysql_error());
			return $e;
		}
	}

	function getPrevious() {
		$display_order = $this->display_order - 1;
		$ma = $this->getAreaObject();
		$m = $ma->getMediaByDisplayOrder($display_order);
		return $m;
	}

	function getNext() {
		$display_order = $this->display_order + 1;
		$ma = $this->getAreaObject();
		$m = $ma->getMediaByDisplayOrder($display_order);
		return $m;
	}
}

?>
